#include "Blocks/ClothingBlock.h"
#include <algorithm>
#include "Log.h"

namespace PocketSurvival
{
    void ClothingBlock::initialize()
    {
        std::map<std::string, ClothingSlot> clothingSlotMap = {
            {"Head", ClothingSlot::Head},
            {"Torso", ClothingSlot::Torso},
            {"Legs", ClothingSlot::Legs},
            {"Feet", ClothingSlot::Feet}};

        std::string clothesText;
        if (Utils::LoadTextFile("./content/Clothes.json", clothesText) == true)
        {
            nlohmann::json clothesJson = nlohmann::json::parse(clothesText);
            for (const auto &clothItemJson : clothesJson)
            {
                int32_t index = clothItemJson["Index"].get<int32_t>();
                int32_t displayIndex = clothItemJson["DisplayIndex"].get<int32_t>();
                std::string slotText = clothItemJson["Slot"].get<std::string>();

                auto it = clothingSlotMap.find(slotText);
                if (it == clothingSlotMap.end())
                {
                    Log::Error(fmt::format("错误的衣服类型: {}, Index: {}", slotText, index));
                    continue;
                }
                ClothingSlot slot = it->second;

                float armorProtection = clothItemJson["ArmorProtection"].get<float>();
                float sturdiness = clothItemJson["Sturdiness"].get<float>();
                float insulation = clothItemJson["Insulation"].get<float>();
                float movementSpeedFactor = clothItemJson["MovementSpeedFactor"].get<float>();
                float steedMovementSpeedFactor = clothItemJson["SteedMovementSpeedFactor"].get<float>();
                float densityModifier = clothItemJson["DensityModifier"].get<float>();
                bool isOuter = clothItemJson["IsOuter"].get<float>();
                bool canBeDyed = clothItemJson["CanBeDyed"].get<float>();
                int32_t layer = clothItemJson["Layer"].get<int32_t>();
                int32_t playerLevelRequired = clothItemJson["PlayerLevelRequired"].get<int32_t>();

                clothingDataVec.emplace_back(index, displayIndex, slot, armorProtection, sturdiness, insulation, movementSpeedFactor, steedMovementSpeedFactor, densityModifier, isOuter, canBeDyed, layer, playerLevelRequired);
            }
        }
        else
        {
            Log::Error("找不到 ./content/Clothes.json 文件");
        }

        dispalyVec = clothingDataVec;
        std::sort(dispalyVec.begin(), dispalyVec.end(), [](const ClothingData &left, const ClothingData &right) -> bool
                  { return left.DisplayIndex < right.DisplayIndex; });

        std::sort(clothingDataVec.begin(), clothingDataVec.end(), [](const ClothingData &left, const ClothingData &right) -> bool
                  { return left.Index < right.Index; });
    }

    void ClothingBlock::getCreativeValues(std::vector<int32_t> &blockVec)
    {
        for (const ClothingData &clothingData : dispalyVec)
        {
            int32_t colorsCount = (clothingData.CanBeDyed == false) ? 1 : 16;
            for (int32_t color = 0; color < colorsCount; color++)
            {
                int32_t data = SetClothingColor(SetClothingIndex(0, clothingData.Index), color);
                blockVec.push_back(Terrain::MakeBlockValue(203, 0, data));
            }
        }
    }
    const ClothingData &ClothingBlock::getClothingData(int32_t value) const
    {
        int32_t num = GetClothingIndex(value);
        return clothingDataVec[num];
    }

    int32_t ClothingBlock::getDamage(int32_t value)
    {
        return (Terrain::ExtractData(value) >> 8) & 0xF;
    }

    int32_t ClothingBlock::setDamage(int32_t value, int32_t damage)
    {
        int32_t num = Terrain::ExtractData(value);
        num = ((num & -3841) | ((damage & 0xF) << 8));
        return Terrain::ReplaceData(value, num);
    }

    int32_t ClothingBlock::getIndex()
    {
        return Index();
    }
    const std::string &ClothingBlock::getBlockName()
    {
        static std::string blockName = "ClothingBlock";
        return blockName;
    }

} // namespace PocketSurvival
